package chapt04.ortho;
// Ortho.java
// OpenGL SuperBible
// Richard S. Wright Jr.
// Demonstrates Orthographic Projection

import javax.media.opengl.GL2;

public class Ortho
{
	// Rotation amounts
	static float xRot = 0.0f;
	static float yRot = 0.0f;
	
	// This function does any needed initialization on the context.  Here it
	// sets up and initializes lighting for the scene.
	protected static void setup(GL2 gl2, int width, int height)
	{
		// Light values and coordinates
		float whiteLight[] = {0.45f, 0.45f, 0.45f, 1.0f};
		float sourceLight[] = {0.25f, 0.25f, 0.25f, 1.0f};
		float lightPos[] = {-50.0f, 25.0f, 250.0f, 0.0f};
		
		gl2.glEnable(GL2.GL_DEPTH_TEST); // Hidden surface removal
		gl2.glFrontFace(GL2.GL_CCW);     // Counter clock-wise polygons face out
		gl2.glEnable(GL2.GL_CULL_FACE);  // Do not calculate inside of jet
	
		// Enable lighting
		gl2.glEnable(GL2.GL_LIGHTING);
		
		// Setup and enable light 0
		gl2.glLightModelfv(GL2.GL_LIGHT_MODEL_AMBIENT, whiteLight, 0);
		gl2.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, sourceLight, 0);
		gl2.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, sourceLight, 0);
		gl2.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightPos, 0);
		gl2.glEnable(GL2.GL_LIGHT0);
		
		// Enable color tracking
		gl2.glEnable(GL2.GL_COLOR_MATERIAL);
		
		// Set Material properties to follow glColor values
		gl2.glColorMaterial(GL2.GL_FRONT, GL2.GL_AMBIENT_AND_DIFFUSE);
		
		// Black blue background
		gl2.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	}
	
	// Called to draw scene
	protected static void render(GL2 gl2, int w, int h)
	{
		float nRange = 120.0f;
		
		// Prevent a divide by zero
		if(h == 0)
			h = 1;
		
		// Set Viewport to window dimensions
		gl2.glViewport(0, 0, w, h);
		
		// Reset coordinate system
		gl2.glMatrixMode(GL2.GL_PROJECTION);
		gl2.glLoadIdentity();
		
		// Establish clipping volume (left, right, bottom, top, near, far)
		if(w <= h)
			gl2.glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange * 2.0f, nRange * 2.0f);
		else
			gl2.glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange * 2.0f, nRange * 2.0f);
		
		gl2.glMatrixMode(GL2.GL_MODELVIEW);
		gl2.glLoadIdentity();
		
		float fZ, bZ;
		
		// Clear the window with current clearing color
		gl2.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
		
		fZ = 100.0f;
		bZ = -100.0f;
		
		// Save the matrix state and do the rotations
		gl2.glPushMatrix();
		gl2.glRotatef(xRot, 1.0f, 0.0f, 0.0f);
		gl2.glRotatef(yRot, 0.0f, 1.0f, 0.0f);
		
		// Set material color, Red
		gl2.glColor3f(1.0f, 0.0f, 0.0f);
		
		// Front Face ///////////////////////////////////
		gl2.glBegin(GL2.GL_QUADS);
			// Pointing straight out Z
			gl2.glNormal3f(0.0f, 0.0f, 1.0f);
			
			// Left Panel
			gl2.glVertex3f(-50.0f, 50.0f, fZ);
			gl2.glVertex3f(-50.0f, -50.0f, fZ);
			gl2.glVertex3f(-35.0f, -50.0f, fZ);
			gl2.glVertex3f(-35.0f, 50.0f, fZ);
			
			// Right Panel
			gl2.glVertex3f(50.0f, 50.0f, fZ);
			gl2.glVertex3f(35.0f, 50.0f, fZ);
			gl2.glVertex3f(35.0f, -50.0f, fZ);
			gl2.glVertex3f(50.0f, -50.0f, fZ);
			
			// Top Panel
			gl2.glVertex3f(-35.0f, 50.0f, fZ);
			gl2.glVertex3f(-35.0f, 35.0f, fZ);
			gl2.glVertex3f(35.0f, 35.0f, fZ);
			gl2.glVertex3f(35.0f, 50.0f, fZ);
			
			// Bottom Panel
			gl2.glVertex3f(-35.0f, -35.0f, fZ);
			gl2.glVertex3f(-35.0f, -50.0f, fZ);
			gl2.glVertex3f(35.0f, -50.0f, fZ);
			gl2.glVertex3f(35.0f, -35.0f, fZ);
			
			// Top length section ////////////////////////////
			// Normal points up Y axis
			gl2.glNormal3f(0.0f, 1.0f, 0.0f);
			gl2.glVertex3f(-50.0f, 50.0f, fZ);
			gl2.glVertex3f(50.0f, 50.0f, fZ);
			gl2.glVertex3f(50.0f, 50.0f, bZ);
			gl2.glVertex3f(-50.0f, 50.0f, bZ);
			
			// Bottom section
			gl2.glNormal3f(0.0f, -1.0f, 0.0f);
			gl2.glVertex3f(-50.0f, -50.0f, fZ);
			gl2.glVertex3f(-50.0f, -50.0f, bZ);
			gl2.glVertex3f(50.0f, -50.0f, bZ);
			gl2.glVertex3f(50.0f, -50.0f, fZ);
			
			// Left section
			gl2.glNormal3f(1.0f, 0.0f, 0.0f);
			gl2.glVertex3f(50.0f, 50.0f, fZ);
			gl2.glVertex3f(50.0f, -50.0f, fZ);
			gl2.glVertex3f(50.0f, -50.0f, bZ);
			gl2.glVertex3f(50.0f, 50.0f, bZ);
			
			// Right section
			gl2.glNormal3f(-1.0f, 0.0f, 0.0f);
			gl2.glVertex3f(-50.0f, 50.0f, fZ);
			gl2.glVertex3f(-50.0f, 50.0f, bZ);
			gl2.glVertex3f(-50.0f, -50.0f, bZ);
			gl2.glVertex3f(-50.0f, -50.0f, fZ);
			
		gl2.glEnd();
		
		gl2.glFrontFace(GL2.GL_CW); // clock-wise polygons face out
		
		gl2.glBegin(GL2.GL_QUADS);
			// Back section
			// Pointing straight out Z
			gl2.glNormal3f(0.0f, 0.0f, -1.0f);
			
			// Left Panel
			gl2.glVertex3f(-50.0f, 50.0f, bZ);
			gl2.glVertex3f(-50.0f, -50.0f, bZ);
			gl2.glVertex3f(-35.0f, -50.0f, bZ);
			gl2.glVertex3f(-35.0f, 50.0f, bZ);
			
			// Right Panel
			gl2.glVertex3f(50.0f, 50.0f, bZ);
			gl2.glVertex3f(35.0f, 50.0f, bZ);
			gl2.glVertex3f(35.0f, -50.0f, bZ);
			gl2.glVertex3f(50.0f, -50.0f, bZ);
			
			// Top Panel
			gl2.glVertex3f(-35.0f, 50.0f, bZ);
			gl2.glVertex3f(-35.0f, 35.0f, bZ);
			gl2.glVertex3f(35.0f, 35.0f, bZ);
			gl2.glVertex3f(35.0f, 50.0f, bZ);
			
			// Bottom Panel
			gl2.glVertex3f(-35.0f, -35.0f, bZ);
			gl2.glVertex3f(-35.0f, -50.0f, bZ);
			gl2.glVertex3f(35.0f, -50.0f, bZ);
			gl2.glVertex3f(35.0f, -35.0f, bZ);
			
			// Insides ////////////////////////////
			gl2.glColor3f(0.75f, 0.75f, 0.75f);
			
			// Normal points up Y axis
			gl2.glNormal3f(0.0f, 1.0f, 0.0f);
			gl2.glVertex3f(-35.0f, 35.0f, fZ);
			gl2.glVertex3f(35.0f, 35.0f, fZ);
			gl2.glVertex3f(35.0f, 35.0f, bZ);
			gl2.glVertex3f(-35.0f, 35.0f, bZ);
			
			// Bottom section
			gl2.glNormal3f(0.0f, 1.0f, 0.0f);
			gl2.glVertex3f(-35.0f, -35.0f, fZ);
			gl2.glVertex3f(-35.0f, -35.0f, bZ);
			gl2.glVertex3f(35.0f, -35.0f, bZ);
			gl2.glVertex3f(35.0f, -35.0f, fZ);
			
			// Left section
			gl2.glNormal3f(1.0f, 0.0f, 0.0f);
			gl2.glVertex3f(-35.0f, 35.0f, fZ);
			gl2.glVertex3f(-35.0f, 35.0f, bZ);
			gl2.glVertex3f(-35.0f, -35.0f, bZ);
			gl2.glVertex3f(-35.0f, -35.0f, fZ);
			
			// Right section
			gl2.glNormal3f(-1.0f, 0.0f, 0.0f);
			gl2.glVertex3f(35.0f, 35.0f, fZ);
			gl2.glVertex3f(35.0f, -35.0f, fZ);
			gl2.glVertex3f(35.0f, -35.0f, bZ);
			gl2.glVertex3f(35.0f, 35.0f, bZ);
		gl2.glEnd();
			
		gl2.glFrontFace(GL2.GL_CCW); // Counter clock-wise polygons face out	
			
		// Restore the matrix state	
		gl2.glPopMatrix();
			
		// Buffer swap
		gl2.glFlush();	
	}
}